trait Base {
  type Exp[T] <: Exp_Base[T]
  trait Exp_Base[T] { self: Exp[T] => }
  
  type Lit[T] <: Exp[T] with Lit_Base[T]
  def Lit[T](value: T): Lit[T]
  trait Lit_Base[T] { self: Lit[T] =>
    val value: T
  } 
}

trait WithEval extends Base { 
  type Exp[T] <: Exp_Base[T] with Exp_WithEval[T]
  trait Exp_WithEval[T] { self : Exp[T] =>
    def eval: T
  }
  
  type Lit[T] <: Exp[T] with Lit_Base[T] with Lit_WithEval[T]
  trait Lit_WithEval[T]  { self : Lit[T] =>  
    def eval: T = value
  }
}

trait WithNeg extends Base  { 
  type Neg <: Exp[Int] with Neg_WithNeg
  def Neg(e: Exp[Int]): Neg
  trait Neg_WithNeg { self : Neg => 
    val e: Exp[Int]
  }
} 

trait NegAndEval extends WithNeg with WithEval {
  type Neg <: Exp[Int] with Neg_WithNeg with Neg_NegAndEval
  trait Neg_NegAndEval extends Exp_WithEval[Int] { self: Neg =>
    def eval = -e.eval
  }
}

class NegAndEval_Deploy extends NegAndEval {
  type Exp[T] = Exp_Base[T] with Exp_WithEval[T]
  
  type Lit[T] = Exp[T] with Lit_Base[T] with Lit_WithEval[T]
  def Lit[T](v: T): Lit[T] = new Exp_Base[T] with Exp_WithEval[T] with Lit_Base[T] with Lit_WithEval[T] { val value = v }
  
  type Neg = Exp[Int] with Neg_WithNeg with Neg_NegAndEval
  def Neg(ee: Exp[Int]): Neg = new Exp_Base[Int] with Exp_WithEval[Int] with Neg_WithNeg with Neg_NegAndEval { val e = ee }
}